﻿#include "msgsocket.h"
#include <QDataStream>
#include <QStringBuilder>
#include <QBuffer>
#include <QImage>

MsgSocket::MsgSocket(QTcpSocket *socket, QObject *parent) : QObject(parent)
{
    m_tcpBlockSize = 0;
    m_tcpSocket = socket;
    connect(m_tcpSocket, SIGNAL(readyRead()),
                this, SLOT(slotReadyRead()));
    connect(m_tcpSocket, SIGNAL(disconnected()),
            m_tcpSocket, SLOT(deleteLater()));
}

MsgSocket::~MsgSocket()
{

}

void MsgSocket::slotReadyRead()
{
    QDataStream in(m_tcpSocket);
    in.setVersion(QDataStream::Qt_5_4);

    if(m_tcpBlockSize == 0)
    {
        if(m_tcpSocket->bytesAvailable()<sizeof(quint16))
        {
            return;
        }
        in >> m_tcpBlockSize;
    }

    if(m_tcpSocket->bytesAvailable() < m_tcpBlockSize)
    {
        return;
    }

    int type;
    in >> type;
    qDebug() << "type = " << type;
    if (type == Msg_Image)
    {
        ImageMsgMap imageMap;
        QByteArray buffer;
        QImage image;
        QString msg;
        in >> msg;
        in >> buffer;

        qDebug() << "Server Recv image: " << msg;
        image.loadFromData(buffer);
        qDebug() << "image.size " << image.width() << image.height();
        imageMap.insert(msg,image);
        GlobalVars::g_ImageMsgQueue.enqueue(imageMap);
    }else
    {
        QString msg;
        in >> msg;
        qDebug() << "Server Recv msg: " << msg;
        if(msg.at(0) == CMD_UserLogin_L)
        {
            parseUserLogin(msg);
        }else if(msg.at(0) == CMD_UserExit_X)
        {
            parseUserExit(msg);
        }else
        {
            GlobalVars::g_msgQueue.enqueue(msg);
        }
    }

    m_tcpBlockSize = 0;
}

bool MsgSocket::slotSendMsg(const QString& msg)
{
       QByteArray buffer;
       QDataStream out(&buffer, QIODevice::WriteOnly);
       out.setVersion(QDataStream::Qt_5_4);
       qDebug() << "Server Send msg: " << msg;

       out << (quint16)0;
       out << Msg_Word;
       out << msg;
       out.device()->seek(0);
       out << (quint16)(buffer.size() - sizeof(quint16));

        return m_tcpSocket->write(buffer);
}

void MsgSocket::slotSendImage(const QString& msg,const QString& path)
{
   QByteArray buffer;
   QDataStream out(&buffer, QIODevice::WriteOnly);
   out.setVersion(QDataStream::Qt_5_4);

   QBuffer buf;
    QImage image(path);
    buf.open(QIODevice::ReadWrite);
    image.save(&buf,"PNG");
    qDebug() << "buf.size() " << buf.size();

   out << (quint16)0;
   out << Msg_Image;
   out << msg;
   out << buf.data();
   out.device()->seek(0);
   out << (quint16)(buffer.size() - sizeof(quint16));

    m_tcpSocket->write(buffer);
}

void MsgSocket::parseUserLogin(QString msg)
{
    QStringList list = msg.split("#").at(1).split("|");             ///msg.remove("L#").split("|");
    QString userID = list.at(0);
    QString password = list.at(1);

    ExecSQL::searchAllUserInfos();
    if (GlobalVars::g_userInfoMap.contains(userID))
    {
        UserInfoList::iterator iter =  GlobalVars::g_userInfoMap[userID];
        if (iter->getPassword() == password)
        {
            QString msg = QString(CMD_UserLogin_L)
                    % QString("#!|") % userID
                    % "|" % iter->getRole();
            this->slotSendMsg(msg);
            emit signalRegisterSocket(userID, this);
        }else
        {
            QString msg = QString(CMD_UserLogin_L)
                    % QString("#?|") % userID
                    % "|密码不正确";
            this->slotSendMsg(msg);
        }
    }
    else{
        QString msg = QString(CMD_UserLogin_L)
                % QString("#?|") % userID
                % "|该账号未注册";
        this->slotSendMsg(msg);
    }
}

void MsgSocket::parseUserExit(QString msg)
{
    qDebug() << "MsgSocket::parseUserExit" << msg;
    QStringList msgList = msg.split("#").at(1).split("|");     //// msg.remove("X#");
    QString userID = msgList.at(1);
    QString type = msgList.at(2);

    emit signalLogoutSocket(userID, this);
    QString msg1 = QString(CMD_UserExit_X)
            % QString("#!|") % userID;

    if(this->slotSendMsg(msg1))
    {
        if (type.toInt() == LogOut_Exit)
        {
            delete this;
        }
    }
}
